package dbu.dbase;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.log4j.Logger;

import common.Configuration;
import common.LogCategory;
import dbu.Data;
import dbu.DbFile;
import dbu.jdbc.JdbcResultSetMetaData;
import dbu.sql.Criteria;
import dbu.sql.Query;
import dbu.sql.SqlCommand;

public class DBaseFile implements DbFile {

	protected static final Logger log = LogCategory.getCategory(DBaseFile.class);

	private String fileName;
	private String path;

	private DBaseHeader header;
	private TableRecords records;

	public DBaseFile(String tableName) {
		Configuration configuration = new Configuration("db.userspropfile", "dbase.properties");
		fileName = configuration.getProperties().getProperty(tableName + ".file");
		path = configuration.getProperties().getProperty("db.path", System.getProperty("user.dir"));
		//charset = configuration.getProperties().getProperty("db.charset", "java.nio.charset.Charset");
		load();
	}

	public void load() {
		File file = new File(path, fileName);
		try {
			InputStream in = new FileInputStream(file);
			byte version = (byte) in.read();
			switch (version) {
				case dbu.dbase.version3.TableFileHeader.VERSION:
					header = new dbu.dbase.version3.TableFileHeader();
					break;
				case dbu.dbase.version7.TableFileHeader.VERSION:
					header = new dbu.dbase.version7.TableFileHeader();
					break;
			}
			((DBaseStructure)header).read(in);
			records = new TableRecords(header);
			records.read(in);
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}

	@Override
	public JdbcResultSetMetaData getMeta() {
		return header.getMeta();
	}

	@Override
	public Data find(Query query) {
		Data data = new Data(getMeta());
		for (DBaseRecord record: records.getRecords()) {
			addBean(data, record, query.getCriteria());
		}
		return data;
	}

	private void addBean(Data data, DBaseRecord record, Criteria criteria) {
		Object[] bean = getBean(record);
		if ((criteria == null) || criteria.evaluate(bean, getMeta())) {
			data.addData(bean);
		}
	}

	private Object[] getBean(DBaseRecord record) {
		Object[] bean = new Object[header.getNumOfFields()];
		for (int i = 0; i < header.getNumOfFields(); i++) {
			bean[i] = record.get(i).toString().trim();
		}
		return bean;
	}

	@Override
	public int insert(SqlCommand sqlCmd) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int update(SqlCommand sqlCmd) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int delete(SqlCommand sqlCmd) {
		// TODO Auto-generated method stub
		return 0;
	}

	static public void main(String[] args) {
		DBaseFile file = new DBaseFile("groups");
		System.out.println(file.header);
		for(DBaseRecord record: file.records.getRecords()) {
			System.out.println(record);
		}
	}

}
